Skip to content

feat(mobile): surface team-vault first-access state on mobile (#70) - #210

Merged
kipavy merged 1 commit into
devfrom
feat/mobile-team-vault-state
Sep 7, 2026
Merged

feat(mobile): surface team-vault first-access state on mobile (#70)#210
kipavy merged 1 commit into
devfrom
feat/mobile-team-vault-state

Conversation

@kipavy

@kipavy kipavy commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Closes the last unbuilt item on #70: mobile surfacing.

The mobile shell rendered no team-vault state at all. A member who opened a keyless team vault got an empty hosts list with no explanation, and the role-aware landing from #186 never fired on mobile — applyFirstViewNav writes uiStore.activeNav, which MobileShell does not read.

What changed

Shared, not copied. TeamVaultState moves out of MainPanel.tsx into src/components/team/TeamVaultStatePanel.tsx unchanged, and the blocked-status rule becomes isBlockedTeamVaultStatus on the store that owns TeamVaultStatus. Both shells read one predicate through useBlockedTeamVault, so the five statuses and the selection rule exist once.

Mobile mount. MobileShell renders the panel above every screen and pushed page when the selected team vault is blocked — the same statuses desktop covers (offline, forbidden, payment_required, awaiting_key, error).

Role-aware landing. applyFirstViewNav gains a mobile branch that navigates through mobileNavStore. firstViewNav is untouched, so the permission-bit rule stays in one place; mobileFirstViewTarget only maps its result onto the mobile shell's two-axis navigation — hosts is a tab, while the keychain and members are pushed pages under More.

Two things the desktop version does not need

The mobile shell has no sidebar, and both of these are dead ends rather than polish:

  • The vault switcher lives only in MobileHeader, inside the tab screens the panel replaces. Covering everything would leave a member who opened a keyless vault with no way back to any other vault. The panel keeps a MobileHeader above it — desktop's sidebar is never covered either, so this is the same rule, not an exception to it: the panel replaces vault contents, not vault chrome.
  • Immersive mode hides the tab bar. With the panel over a live terminal that would remove the last navigation on screen, so immersive is suppressed while blocked.

Both are pinned by tests that failed for the right reason before the fix.

The session and SFTP layers stay mounted under the panel — unmounting them would drop a live terminal or an SFTP connection. The plain tab screens are unmounted, since they only list vault objects and the panel covers them.

No new strings: mobile reuses the existing layout.mainPanel.teamVault.* keys.

Verification

npx tsc --noEmit clean. 232 test files / 1738 tests pass across every directory the diff touches (services, stores, hooks, components/{team,mobile,layout}), plus the two cross-directory importers (runtime.mobileScreen, VaultShareSheet). New tests: the mobile nav mapping, the shell-aware landing on both shells, the blocked-status rule, the shared panel's copy, and the four MobileShell mount cases including the two dead ends above.

Not device-verified. No adb, emulator, or /dev/kvm on the dev box, so the layout in a real WebView and the two-account keyless window were not exercised on hardware. That gate is still owed before #70's mobile checkbox is ticked.

The mobile shell rendered no team-vault state at all, so a member who
opened a keyless team vault saw an empty hosts list with no explanation,
and the role-aware landing never fired: applyFirstViewNav writes
uiStore.activeNav, which MobileShell does not read.

Extract the desktop panel and its predicate so both shells share them,
then mount the panel in MobileShell and give applyFirstViewNav a mobile
branch that navigates through mobileNavStore instead.

MobileHeader rides above the panel because it owns the only route to the
vault switcher on mobile; without it a member who opened a keyless vault
could never reach another one. Immersive mode is suppressed for the same
reason: it hides the tab bar. The session and SFTP layers stay mounted
under the panel so a live terminal or SFTP connection survives.

No new strings — mobile reuses the existing teamVault keys.
@kipavy
kipavy merged commit 66d31f0 into dev Sep 7, 2026
4 checks passed
@kipavy
kipavy deleted the feat/mobile-team-vault-state branch September 7, 2026 11:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant